package com.fs.uc.api.user.resource;

import com.fs.uc.api.user.dto.*;
import com.fs.uc.api.user.service.CommonService;
import com.fs.uc.base.Const;
import com.fs.uc.core.ModuleState;
import com.fs.uc.core.SubjectType;
import com.fs.uc.nacos.BasicInfoService;
import com.fs.uc.nacos.dto.Staff;
import com.fs.uc.nacos.dto.TenantStaff;
import com.fs.uc.security.Auth;
import com.fs.uc.security.AuthContext;
import com.fs.uc.base.domain.*;
import com.fs.uc.base.exception.CustomException;
import com.fs.uc.base.repo.MenuRepository;
import com.fs.uc.base.repo.ModuleRepository;
import com.fs.uc.base.repo.OrgRepository;
import com.fs.uc.base.repo.PersonRepository;
import org.wildfly.common.Assert;

import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户中心基本api，面向所有用户
 * 原UserController
 *
 * @author 崔超
 * 2021/12/7
 */
@Auth
@Path(Const.URL_PREFIX + "/user")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Transactional
public class CommonResource {

    @Inject
    CommonService commonService;
    @Inject
    ModuleRepository moduleRepo;
    @Inject
    OrgRepository orgRepo;
    @Inject
    PersonRepository personRepo;
    @Inject
    MenuRepository menuRepo;
    @Inject
    BasicInfoService basicInfoService;

    @GET
    @Path("/parks")
    public List<ParkInfo> getParks(){
        List<Org> parks = orgRepo.findByType(OrgType.Park);
        return parks.stream().map(park->new ParkInfo(park.id,park.name)).collect(Collectors.toList());
    }

    /**
     *校验当前用户,获取姓名信息
     */
    @GET
    @Path("/current")
    public RespUser currentUser() {

        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();

        return commonService.getSubjectInfo(subjectId, subjectType);
    }


    /**
    *获取当前用户所有的模块状态
     */
    @GET
    @Path("/module")
    public List<RespModule> getModules() {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();

        Set<FunctionalModule> authorizedModule = commonService.getAuthorizedModule(subjectId, subjectType);
        return moduleRepo.findAll().stream().map(module -> {
            boolean in = authorizedModule.contains(module);
            return in ? new RespModule(module.name, module.humanName, ModuleState.HasOpen)
                    : new RespModule(module.name, module.humanName, ModuleState.NotOpen);
        }).collect(Collectors.toList());

    }

    /**
     * 获取当前用户所有的付费模块的状态及价格
     */
    @GET
    @Path("/module/pay")
    public List<RespModuleWithPrice> getPayModules() {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();

        Set<FunctionalModule> authorizedModule = commonService.getAuthorizedModule(subjectId, subjectType);
        return moduleRepo.findAll().stream()
                .filter(module -> !module.free)
                .map(module -> {
                    boolean in = authorizedModule.contains(module);
                    return in ? new RespModuleWithPrice(module.name, module.humanName, ModuleState.HasOpen, module.price)
                            : new RespModuleWithPrice(module.name, module.humanName, ModuleState.NotOpen, module.price);
                }).collect(Collectors.toList());
    }

    /**
     * 获取当前用户角色和用户类型
     */
    @GET
    @Path("/role-and-type")
    public RespUserTypeAndRole getRolesAndUserType() {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();

        Set<Role> rolesOfUser = commonService.getRolesOfUser(subjectId, subjectType);
        List<DtoRole> dtoRoles = rolesOfUser.stream().map(r -> new DtoRole(r.id, r.name)).collect(Collectors.toList());

        String identityType = commonService.getIdentityType(subjectId, subjectType);

        return new RespUserTypeAndRole(identityType, dtoRoles);
    }

    /**
     * 修改密码(实体web账户）
     */
    @PUT
    @Path("/pwd")
    public void resetPassword(@Valid ReqUpdateUserPassword req) {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();
        Assert.assertTrue(subjectType == SubjectType.Org);

        Org org = orgRepo.getById(subjectId);
        if (!req.getOldPassword().equals(org.password)) {
            throw new CustomException("原始密码错误");
        }

        org.password = req.getNewPassword();
        orgRepo.updateOrg(org);
    }

    /**
     *查询用户已绑定的自定义菜单
     */
    @GET
    @Path("/menu")
    public RespMenu getCustomMenuOfUser() {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();
        Assert.assertTrue(subjectType == SubjectType.Org);
        CustomMenu cm = menuRepo.findById(subjectId);
        if (cm == null)
            return new RespMenu("");
        else
            return new RespMenu(cm.menu);
    }

    /**
     * 绑定自定义菜单
     */
    @POST
    @Path("/menu")
    public void bindMenus(@Valid ReqBindMenu req) {
        Long subjectId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();
        Assert.assertTrue(subjectType == SubjectType.Org);

        CustomMenu cm = menuRepo.findById(subjectId);
        if (cm == null) {
            cm = new CustomMenu();
            cm.userId = subjectId;
            cm.menu = req.getMenuJson();
            menuRepo.persist(cm);
        }else{
            cm.menu=req.getMenuJson();
        }
    }

    /**
     * 获取当前个人用户所有身份
     */
    @GET
    @Path("/identities")
    public List<UserIdentity> getIdentitiesOfUser() {
        Long personId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();
        if (subjectType == SubjectType.Org) {
            throw new CustomException("组织实体用户无需此操作");
        }

        Person person = personRepo.getById(personId);
        return person.orgs.stream().map(org -> {
            if (org.type == OrgType.Park) {
                TenantStaff tenantStaff = basicInfoService.getTenantStaff(org.id, personId);
                return new UserIdentity(personId, org.name, org.id, tenantStaff.name, person.phone);
            } else {
                Staff staff = basicInfoService.getStaff(org.remoteId, personId);
                return new UserIdentity(personId, org.name, org.id, staff.name, person.phone);
            }
        }).collect(Collectors.toList());
    }

    /**
     * 切换身份
     */
    @POST
    @Path("/identity")
    public RespSwitchIdentity switchIdentity(@Valid ReqSwitchIdentity req) {
        Long personId = AuthContext.getSubjectId();
        SubjectType subjectType = AuthContext.getSubjectType();
        if (subjectType == SubjectType.Org) {
            throw new CustomException("组织实体用户无需此操作");
        }

        String token = commonService.switchOrg(personId, req.getOrgId());
        return new RespSwitchIdentity(token);
    }

    /**
     * 小程序上获取园区下CustomUser身份信息
     */
    @GET
    @Path("/user_info")
    public RespPersonInfoAndOrg getCustomUserInfo() {
        Long personId = AuthContext.getSubjectId();
        Long parkId=commonService.fetchUserParkId(AuthContext.getSubjectType(), personId);

        Person person = personRepo.getById(personId);
        Org org = orgRepo.getById(parkId);

        TenantStaff tenantStaff = basicInfoService.getTenantStaff(parkId, personId);

        return new RespPersonInfoAndOrg(person.id, org.name
                , tenantStaff.name, person.phone);
    }

    /**
     * 获取访客个人信息
     */
    @GET
    @Path("/visitor/info")
    public RespPersonInfo getVisitorInfo(){
        Long personId = AuthContext.getSubjectId();
        Person person = personRepo.getById(personId);
        return new RespPersonInfo(person.name, person.phone);
    }

    /**
     * 退出登录
     */
    @POST
    @Path("/logout")
    public void WechatLogout() {
    }
}
